﻿using XNAFight.Scene.Core;
using Microsoft.Xna.Framework;
using XNAFight.Engine.Inputs;
using System;
using System.Collections.Generic;
using Microsoft.Xna.Framework.Input;

namespace XNAFight.Scene.CharacterSelection
{
    class SingleControlPicker : UpdatedComponent
    {
        #region CHAMPS

        // Index du joueur
        private int player_id;

        // Peripheriques du joueur
        private Controler controler;

        // True si le peripherique du joueur est bien enregistré
        private bool controler_ok;
        
        // Liste des controlers qu'il ne faut pas enregistrer
        private List<Controler> forbidden_controlers;
        
        #endregion

        #region PROPRIETES

        public Controler Controler
        {
            get { return controler; }
        }

        public int PlayerID
        {
            get { return player_id; }
        }

        public bool IsControlerOk
        {
            get { return controler_ok; }
            set { controler_ok = value; }
        }

        #endregion
        
        #region INITIALISATION

        public SingleControlPicker(Game _game, int _player_id)
            : base(_game)
        {
            player_id = _player_id;

            controler = new Controler();
            forbidden_controlers = new List<Controler>();

            ActivationDelay = 2;
        }
        
        #endregion

        #region UPDATE / DRAW

        public override void Update(GameTime _game_time)
        {
            base.Update(_game_time);
        }
        /*
        public override void Draw(GameTime _game_time)
        {
            base.Draw(_game_time);

            CommonContent.SpriteBatch.Begin();

            Color activation_color = Color.Black;
            if (!this.IsListeningInputs)
                activation_color = Color.Gray;

            CommonContent.SpriteBatch.DrawString(CommonContent.DefaultFont, "Player " + index.ToString() + ":", pos_text, activation_color, 0, origin, 0.8f, SpriteEffects.None, 0);
            if (!controler_ok)
                CommonContent.SpriteBatch.DrawString(CommonContent.DefaultFont, "Press \"Start\" or \"Enter\"", pos_text_bis, activation_color, 0, origin, 0.8f, SpriteEffects.None, 0);
            else
            {
                if (controler.Type == InputType.Keyboard)
                    CommonContent.SpriteBatch.DrawString(CommonContent.DefaultFont, "Keyboard", pos_text_bis, activation_color, 0, origin, 0.8f, SpriteEffects.None, 0);
                else
                    CommonContent.SpriteBatch.DrawString(CommonContent.DefaultFont, "Pad " + controler.Index.ToString(), pos_text_bis, activation_color, 0, origin, 0.8f, SpriteEffects.None, 0);
            }

            CommonContent.SpriteBatch.End();
        }
        */
        #endregion

        #region INPUTS

        public override void HandleInputs()
        {
            if (InputState.isNewKeyPressed(Keys.Enter))
            {
                registerKeyboard();
            }
            if (InputState.isNewButtonPressed(Buttons.Start))
            {
                registerPad();
            }

            if (InputState.isNewKeyPressed(Keys.Escape))
            {
                keyboardCancel();
            }
            if (InputState.isNewButtonPressed(Buttons.B) || InputState.isNewButtonPressed(Buttons.Back))
            {
                padCancel();
            }
        }

        #endregion

        #region AUTRES METHODES

        public override void Reset()
        {
            controler_ok = false;
            forbidden_controlers.Clear();
        }
        
        public void registerKeyboard()
        {
            if (controler_ok)
                return;

            controler.Type = InputType.Keyboard;

            if (isForbidden(controler))
                return;

            controler_ok = true;
            OnComplete();
        }

        public void registerPad()
        {
            if (controler_ok)
                return;

            if (!registerPad(PlayerIndex.One))
                if (!registerPad(PlayerIndex.Two))
                    if (!registerPad(PlayerIndex.Three))
                        registerPad(PlayerIndex.Four);
        }
        public bool registerPad(PlayerIndex _pad_index)
        {
            bool registered = false;

            if (InputState.isNewButtonPressed(Buttons.Start, _pad_index))
            {                
                controler.Type = InputType.Pad;
                controler.Index = _pad_index;

                if (!isForbidden(controler))
                {
                    controler_ok = true;
                    registered = true;
                    OnComplete();
                }
            }

            return registered;
        }

        public void forbidControler(Controler _controler)
        {
            forbidden_controlers.Add(_controler);
        }
        public void allowControler(Controler _controler)
        {
            forbidden_controlers.Remove(_controler);
        }

        public bool isForbidden(Controler _controler)
        {
            bool is_forbidden = false;

            int i = 0;
            while (i < forbidden_controlers.Count && !is_forbidden)
            {
                if (forbidden_controlers[i] == _controler)
                    is_forbidden = true;
                i++;
            }

            return is_forbidden;
        }

        public void keyboardCancel()
        {
            if (!isForbidden(new Controler(InputType.Keyboard)))
                OnCancelling();
        }
        public void padCancel()
        {
            if (!padCancel(PlayerIndex.One))
                if (!padCancel(PlayerIndex.Two))
                    if (!padCancel(PlayerIndex.Three))
                        padCancel(PlayerIndex.Four);
        }
        public bool padCancel(PlayerIndex _index)
        {
            if (!isForbidden(new Controler(InputType.Pad, _index)))
                OnCancelling();
            else
                return false;

            return true;
        }

        #endregion
    }
}